home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / dev / e / OBEdit_src.lha / OBEdit.e < prev   
Text File  |  1999-05-28  |  13KB  |  462 lines

  1. /*
  2.     Read a file (obdata.dat) manipulate records in it.
  3.  
  4.     This program is 1999 © Kay Ove Ovesen. You may spread it freely, as long as
  5.     the original archive contents is unchanged. You may include parts of the
  6.     code in your own programs without permission from the author.
  7.  
  8.     The program was written under OS 3.0 and compiled with AmigaE v3.3a.
  9.  
  10. */
  11.  
  12. MODULE 'tools/file', 'tools/exceptions'
  13.  
  14. /*    For practical reasons, some variables are defined globally */
  15.  
  16. DEF obfile, oblen, obname, y, verbose=0
  17.  
  18.     /* OBJECT INITIALIZATION */
  19.  
  20. OBJECT weapon
  21.     name[20]:ARRAY        ->Offset 00
  22.     damage:CHAR            ->Offset 16
  23.     ammo1:CHAR            ->Offset 1A
  24.     ammo2:CHAR            ->Offset 1B
  25.     ammo3:CHAR            ->Offset 1C
  26.     dtype:CHAR            ->Offset 1F
  27.     accauto:CHAR        ->Offset 20
  28.     accsnap:CHAR        ->Offset 21
  29.     accaimed:CHAR        ->Offset 22
  30.     timeauto:CHAR        ->Offset 23
  31.     timesnap:CHAR        ->Offset 24
  32.     timeaimed:CHAR        ->Offset 25
  33.     ammords:CHAR        ->Offset 26
  34. ENDOBJECT
  35.  
  36. /*    END Object init */
  37.  
  38. /* OBJECT Methods */
  39.  
  40. PROC readobvalues(y) OF weapon
  41.     MidStr(self.name,obfile,y)
  42.     self.damage:=obfile[y+22]
  43.     self.ammo1:=obfile[y+26]
  44.     self.ammo2:=obfile[y+27]
  45.     self.ammo3:=obfile[y+28]
  46.     self.dtype:=obfile[y+31]
  47.     self.accauto:=obfile[y+32]
  48.     self.accsnap:=obfile[y+33]
  49.     self.accaimed:=obfile[y+34]
  50.     self.timeauto:=obfile[y+35]
  51.     self.timesnap:=obfile[y+36]
  52.     self.timeaimed:=obfile[y+37]
  53.     self.ammords:=obfile[y+38]
  54. ENDPROC
  55.  
  56. PROC writeobvalues(y, wep:PTR TO weapon)
  57.     obfile[y+22]:=wep.damage
  58.     obfile[y+26]:=wep.ammo1
  59.     obfile[y+27]:=wep.ammo2
  60.     obfile[y+28]:=wep.ammo3
  61.     obfile[y+31]:=wep.dtype
  62.     obfile[y+32]:=wep.accauto
  63.     obfile[y+33]:=wep.accsnap
  64.     obfile[y+34]:=wep.accaimed
  65.     obfile[y+35]:=wep.timeauto
  66.     obfile[y+36]:=wep.timesnap
  67.     obfile[y+37]:=wep.timeaimed
  68.     obfile[y+38]:=wep.ammords
  69. ENDPROC
  70.  
  71. PROC impvalues(rcd, wepname) OF weapon
  72. /*    All values are checked for valid ranges before import */
  73.  
  74. ->    StrCopy(self.name, wepname)
  75.  
  76.     IF (rcd[2]>255) OR (rcd[2]<0)
  77.         PrintF('\tWARNING: Damage for object #\d (\s) is out of range!\n', rcd[0], wepname)
  78.         RETURN 1
  79.     ELSE
  80.         self.damage:=rcd[2]
  81.     ENDIF
  82.  
  83.     IF ((rcd[3]<>255) AND ((rcd[3]>79) OR (rcd[4]<0)))
  84.         PrintF('\tWARNING: Ammo1 for object #\d (\s) is out of range!\n', rcd[0], wepname)
  85.         RETURN 1
  86.     ELSE
  87.         self.ammo1:=rcd[3]
  88.     ENDIF
  89.  
  90.     IF ((rcd[4]<>255) AND ((rcd[4]>79) OR (rcd[4]<0)))
  91.         PrintF('\tWARNING: Ammo2 for object #\d (\s) is out of range!\n', rcd[0], wepname)
  92.         RETURN 1
  93.     ELSE
  94.         self.ammo2:=rcd[4]
  95.     ENDIF
  96.  
  97.     IF ((rcd[5]<>255) AND ((rcd[5]>79) OR (rcd[5]<0)))
  98.         PrintF('\tWARNING: Ammo3 for object #\d (\s) is out of range!\n', rcd[0], wepname)
  99.         RETURN 1
  100.     ELSE
  101.     self.ammo3:=rcd[5]
  102.     ENDIF
  103.  
  104.     IF (rcd[6]>255) OR (rcd[6]<0) OR ((rcd[6]>6) AND (rcd[6]<255))
  105.         PrintF('\tWARNING: Damagetype for object #\d (\s) is out of range!\n', rcd[0], wepname)
  106.         RETURN 1
  107.     ELSE
  108.         self.dtype:=rcd[6]
  109.     ENDIF
  110.  
  111.     IF (rcd[7]>255) OR (rcd[7]<0)
  112.         PrintF('\tWARNING: AccAuto for object #\d (\s) is out of range!\n', rcd[0], wepname)
  113.         RETURN 1
  114.     ELSE
  115.         self.accauto:=rcd[7]
  116.     ENDIF
  117.  
  118.     IF (rcd[8]>255) OR (rcd[8]<0)
  119.         PrintF('\tWARNING: AccSnap for object #\d (\s) is out of range!\n', rcd[0], wepname)
  120.         RETURN 1
  121.     ELSE
  122.         self.accsnap:=rcd[8]
  123.     ENDIF
  124.  
  125.     IF (rcd[9]>255) OR (rcd[9]<0)
  126.         PrintF('\tWARNING: AccAimed for object #\d (\s) is out of range!\n', rcd[0], wepname)
  127.         RETURN 1
  128.     ELSE
  129.         self.accaimed:=rcd[9]
  130.     ENDIF
  131.  
  132.     IF (rcd[10]>100) OR (rcd[10]<0)
  133.         PrintF('\tWARNING: TimeAuto for object #\d (\s) is out of range!\n', rcd[0], wepname)
  134.         RETURN 1
  135.     ELSE
  136.         self.timeauto:=rcd[10]
  137.     ENDIF
  138.  
  139.     IF (rcd[11]>100) OR (rcd[11]<0)
  140.         PrintF('\tWARNING: TimeSnap for object #\d (\s) is out of range!\n', rcd[0], wepname)
  141.         RETURN 1
  142.     ELSE
  143.         self.timesnap:=rcd[11]
  144.     ENDIF
  145.  
  146.     IF (rcd[12]>100) OR (rcd[12]<0)
  147.         PrintF('\tWARNING: TimeAimed for object #\d (\s) is out of range!\n', rcd[0], wepname) 
  148.         RETURN 1
  149.     ELSE
  150.         self.timeaimed:=rcd[12]
  151.     ENDIF
  152.  
  153.     IF (rcd[13]>255) OR (rcd[13]<0)
  154.         PrintF('\nWARNING: AmmoRds for object #\d (\s) is out of range!\n', rcd[0], wepname)
  155.         RETURN 1
  156.     ELSE
  157.         self.ammords:=rcd[13]
  158.     ENDIF
  159. ENDPROC
  160.  
  161. PROC printobvalues(wep:PTR TO weapon)
  162.     PrintF('\nName:\t\t\s', wep.name)
  163.     PrintF('\nDamage:\t\t\d', wep.damage)
  164.     PrintF('\nDmgType:\t\d', wep.dtype)
  165.     PrintF('\nRounds:\t\t\d', wep.ammords)
  166.     PrintF('\nAmmo 1:\t\t\d', wep.ammo1)
  167.     PrintF('\nAmmo 2:\t\t\d', wep.ammo2)
  168.     PrintF('\nAmmo 3:\t\t\d', wep.ammo3)
  169.     PrintF('\nAcc. Auto:\t\d', wep.accauto)
  170.     PrintF('\nAcc. Snap:\t\d', wep.accsnap)
  171.     PrintF('\nAcc. Aimed:\t\d', wep.accaimed)
  172.     PrintF('\nTU Auto:\t\d', wep.timeauto)
  173.     PrintF('\nTU Snap:\t\d', wep.timesnap)
  174.     PrintF('\nTU Aimed:\t\d', wep.timeaimed)
  175.     PrintF('\n\n')
  176. ENDPROC
  177.  
  178. /*    END Object methods */
  179.  
  180. PROC main() HANDLE
  181.     DEF templ, rdargs, args=NIL:PTR TO LONG
  182.     DEF wep:PTR TO weapon
  183.     templ:='FILE/M,OPT2/K,OPT3/K'
  184.     rdargs:=ReadArgs(templ,{args},NIL)
  185.  
  186.     PrintF('\n\t***   UFO Weapons editor v1.1   ***\n')
  187.  
  188.     IF args[0]=NIL
  189.         PrintF('\nUsage: OBEdit <FILENAME> <RECORD>')
  190.         PrintF('\nWhere <FILENAME> is file to scan and <RECORD> is #record to display.\n')
  191.         PrintF('If <RECORD> is ommitted or out of range, the program will list all records in file.\n')
  192.         PrintF('If <RECORD> is "all" then the program will list ALL objects in the file.\n\n')
  193.         PrintF('Use "exportrff" <FILENAME> to make an RFF 1.1-compatible database file.\n')
  194.         PrintF('Use "exportcsv" <FILENAME> to make an ASCII-standard Comma-separated database\n')
  195.         PrintF('file with headers. (Compatible with most database programs and spreadsheets.)\n')
  196.         PrintF('Use "ex" for a short list of examples.\n')
  197.         RETURN
  198.     ENDIF
  199.  
  200.     IF StrCmp(LowerStr(args[0]),'ex') THEN printexamples()
  201.  
  202.     obfile,oblen:=readfile(args[0])
  203.     PrintF('File: \s', args[0])
  204.     PrintF('\nSize: \d bytes.',oblen)
  205.     IF oblen=4320
  206.         PrintF('\nFile seems to be of correct lenght.\n')
  207.         obname:=args[0]
  208.     ELSE
  209.         PrintF('File is not of correct lenght.\n')
  210.         RETURN
  211.     ENDIF
  212.  
  213.     IF StrCmp(LowerStr(args[1]),'exportcsv')
  214.         IF (StrCmp(LowerStr(args[3]),'verbose') OR StrCmp(LowerStr(args[3]),'v')) THEN verbose:=1
  215.         writecsv(args[2], LowerStr(args[3]))
  216.         RETURN
  217.     ENDIF
  218.  
  219.     IF StrCmp(LowerStr(args[1]),'exportrff')
  220.         IF (StrCmp(LowerStr(args[3]),'verbose') OR StrCmp(LowerStr(args[3]),'v')) THEN verbose:=1
  221.         writerff(args[2], LowerStr(args[3]))
  222.         RETURN
  223.     ENDIF
  224.  
  225.     IF StrCmp(LowerStr(args[1]),'import')
  226.         IF (StrCmp(LowerStr(args[3]),'verbose') OR StrCmp(LowerStr(args[3]),'v')) THEN verbose:=1
  227.         checkformat(args[2])
  228.         RETURN
  229.     ENDIF
  230.  
  231.     IF StrCmp(LowerStr(args[1]),'all')
  232.         FOR y:=0 TO (oblen-54) STEP 54
  233.             PrintF('\nIndex:\t\t\d',y/54)
  234.             NEW wep
  235.             wep.readobvalues(y)
  236.             printobvalues(wep)
  237.             END wep
  238.             IF CtrlC() THEN CleanUp()
  239.         ENDFOR
  240.         RETURN
  241.     ENDIF
  242.  
  243.     y:=(Val(args[1])*54)
  244.     IF y>(oblen-54)
  245.         PrintF('\nERROR: Record \d does not exist in \s!\n', Val(args[1]), args[0])
  246.         listrecords()
  247.         RETURN
  248.     ENDIF
  249.     
  250.     IF args[1]=NIL
  251.         listrecords()
  252.         RETURN
  253.     ENDIF
  254.  
  255.     PrintF('\nEntry:\t\t\d', Val(args[1]))
  256.     NEW wep
  257.     wep.readobvalues(y)
  258.     printobvalues(wep)
  259.     END wep
  260.  
  261. EXCEPT
  262.     report_exception()
  263. ENDPROC
  264.  
  265. PROC listrecords() ->If no record number is given, this will simply list all records in the file.
  266.     ->DEF hexnumber
  267.     DEF navn
  268.  
  269.     PrintF('\nIndex:\tName:\n---------------------------\n')
  270.     FOR y:=0 TO (oblen-54) STEP 54
  271.         IF CtrlC() THEN CleanUp()
  272.         navn:=obfile+y
  273.         IF (y/54)<10
  274.             PrintF('0')
  275.         ENDIF
  276.         ->hexnumber:=(y/54)
  277.         ->hexnumber:=Val($hexnumber)
  278.         PrintF('\d\t\s\n', y/54, navn)
  279.     ENDFOR
  280. ENDPROC
  281.  
  282. PROC writecsv(csvfile, verb)
  283.     DEF wep:PTR TO weapon
  284.     DEF tempstring[60]:STRING
  285.     DEF em[4000]:STRING
  286.     StrCopy(em, 'Index,Name,Damage,Ammo1,Ammo2,Ammo3,DmgType,Accauto,Accsnap,Accaimed,TUAuto,TUSnap,TUAimed,Rounds\n')
  287.     FOR y:=0 TO (IF StrCmp(verb, 'all') THEN oblen-54 ELSE 2646) STEP 54
  288.         IF CtrlC() THEN CleanUp()
  289.         NEW wep
  290.         wep.readobvalues(y)
  291.         StringF(tempstring,'\d,\s,\d,\d,\d,\d,\d,\d,\d,\d,\d,\d,\d,\d\n', (y/54),wep.name,wep.damage,wep.ammo1,wep.ammo2,wep.ammo3,wep.dtype,wep.accauto,wep.accsnap,wep.accaimed,wep.timeauto,wep.timesnap,wep.timeaimed,wep.ammords)
  292.         IF (verbose<>0) THEN PrintF('Found weapon "\s" at index #\d.\n', wep.name, y/54)
  293.         END wep
  294.         StrAdd(em,tempstring)
  295.     ENDFOR
  296.     StrAdd(em, '\0')
  297.     writefile(csvfile,em,StrLen(em))
  298.     PrintF('\nWrote CSV-file "\s".\n\n', csvfile)
  299.     CleanUp()
  300. ENDPROC
  301.  
  302. PROC writerff(rffile, verb)
  303.     DEF wep:PTR TO weapon
  304.     DEF tempstring[60]:STRING ->rffhdr[550]:STRING
  305.     DEF em[5000]:STRING
  306.  
  307. /*    Creating RFF header */
  308.  
  309.     StrCopy(em, 'Index\tName\tDamage\tAmmo1\tAmmo2\tAmmo3\tDmgType\tAccauto\tAccsnap\tAccaimed\tTUAuto\tTUSnap\tTUAimed\tRounds\n')
  310.  
  311.     IF FileLength('s:OBEdit.hdr')>-1    ->Check for a custom RFF header file and load this if possible.
  312.         StrAdd(em, readfile('s:OBEdit.hdr', 0))
  313.         PrintF('\nUsing custom RFF header from S:OBEdit.hdr\n')
  314.     ELSE                                        ->If no custom RFF header is found, default values are used.
  315.         PrintF('\nS:OBEdit.hdr not found, using built-in default.\n')
  316.         StrAdd(em, '@RFF=1.1,TYPE=form\tFTYP=text,NAME=Index,OFFS=0,SIZE=3,NEXT=tab\tFTYP=text,NAME=Name,OFFS=1,SIZE=22,NEXT=nl\tFTYP=cycle,CENT=0,CENT=1,CENT=2,CENT=3,CENT=4,CENT=5,CENT=6,CENT=255,NAME=DmgType,OFFS=6,SIZE=6,NEXT=tab\tNAME=Damage,OFFS=2,SIZE=3,NEXT=tab\tNAME=Rounds,OFFS=13,SIZE=3,NEXT=nl\tNAME=Ammo1,OFFS=3,SIZE=3,NEXT=tab\tNAME=Ammo2,OFFS=4,SIZE=3,NEXT=tab\tNAME=Ammo3,OFFS=5,SIZE=3,NEXT=nl\tNAME=Accauto,OFFS=7,SIZE=3,NEXT=tab\tNAME=Accsnap,OFFS=8,SIZE=3,NEXT=tab\tNAME=Accaimed,OFFS=9,SIZE=3,NEXT=nl\tNAME=TUAuto,OFFS=10,SIZE=3,NEXT=tab\tNAME=TUSnap,OFFS=11,SIZE=3,NEXT=tab\tNAME=TUAimed,OFFS=12,SIZE=3,NEXT=para\n')
  317.     ENDIF
  318.  
  319. /*    Reading values from .dat file in memory and create an RFF file. */
  320.  
  321.     FOR y:=0 TO (IF StrCmp(verb, 'all') THEN oblen-54 ELSE 2646) STEP 54
  322.         IF CtrlC() THEN CleanUp()
  323.         NEW wep
  324.         wep.readobvalues(y)
  325.         StringF(tempstring,'\d\t\s\t\d\t\d\t\d\t\d\t\d\t\d\t\d\t\d\t\d\t\d\t\d\t\d\n', (y/54),wep.name,wep.damage,wep.ammo1,wep.ammo2,wep.ammo3,wep.dtype,wep.accauto,wep.accsnap,wep.accaimed,wep.timeauto,wep.timesnap,wep.timeaimed,wep.ammords)
  326.         IF (verbose<>0) THEN PrintF('Found weapon "\s" at index #\d.\n', wep.name, y/54)
  327.         END wep
  328.         StrAdd(em,tempstring)
  329.     ENDFOR
  330.     StrAdd(em, '\0') -> Making sure the file is null-terminated
  331.  
  332.     writefile(rffile,em,StrLen(em))
  333.     PrintF('\nWrote RFF-file "\s".\n\n', rffile)
  334.     CleanUp()
  335. ENDPROC
  336.  
  337. PROC checkformat(infile)
  338.     DEF fhandle, firstline[30]:STRING
  339.     
  340.     IF fhandle:=Open(infile, OLDFILE)
  341.         Fgets(fhandle,firstline,30)
  342.         Close(fhandle)
  343.     ELSE
  344.         PrintF('\nCould not open file "\s".',infile)
  345.         RETURN
  346.     ENDIF
  347.  
  348.     IF (InStr(firstline, ',')<>-1)
  349.         PrintF('\nFile "\s" is CSV-ADCH format.\n', infile)
  350.         importcsv(infile)
  351.     ELSEIF (InStr(firstline,'    ')<>-1)
  352.         PrintF('\nFile "\s" is RFF-DB format.\n', infile)
  353.         importrff(infile)
  354.     ELSE
  355.         PrintF('\nABORTED: File "\s" has an unknown format.\n', infile)
  356.     ENDIF
  357. ENDPROC
  358.  
  359. PROC importrff(infile)
  360.     DEF rff, len
  361.     DEF start=0, end
  362.     rff, len:=readfile(infile)
  363.  
  364. /*    Skip to the first line after the RFF header.*/
  365.  
  366.     IF InStr(rff, '@')<>-1
  367.         start:=InStr(rff, '\n', InStr(rff, '@', start))+1
  368.     ELSE
  369.         start:=InStr(rff, '\n', start)+1
  370.     ENDIF
  371.  
  372.     REPEAT
  373.         end:=InStr(rff, '\n', start)
  374.         IF end<>-1 THEN rff[end]:=NIL
  375.         procline(rff+start, '    ')
  376.         start:=end+1
  377.     UNTIL (start>=len) OR (end=-1)
  378.  
  379.     writefile(obname, obfile, oblen)
  380.     PrintF('\nSuccessfully imported RFF file to "\s".\n', obname)
  381.     RETURN
  382. ENDPROC
  383.  
  384. PROC importcsv(infile)
  385.     DEF csv, len
  386.     DEF start=0, end
  387.     csv,len:=readfile(infile)
  388.  
  389. /*    Skip the first line containing the headers.*/
  390.  
  391.     start:=InStr(csv, '\n',start)+1
  392.  
  393.     REPEAT
  394.         end:=InStr(csv, '\n', start)
  395.         IF end<>-1 THEN csv[end]:=NIL
  396.         procline(csv+start, ',')
  397.         start:=end+1
  398.     UNTIL (start>=len) OR (end=-1)
  399.  
  400.     writefile(obname, obfile, oblen)
  401.     PrintF('\nSuccessfully imported CSV file to "\s".\n', obname)
  402.  
  403.     RETURN
  404. ENDPROC
  405.  
  406. PROC procline(line, delim)
  407.     DEF start=0, end, s, i=0
  408.     DEF rcd[14]:STRING, errline[76]:STRING, wepname[20]:STRING
  409.     DEF wep:PTR TO weapon
  410.  
  411.     IF StrLen(line)<20 THEN RETURN
  412.     StrCopy(errline, line)
  413.     REPEAT
  414.         end:=InStr(line,delim,start)
  415.         IF end<>-1 THEN line[end]:=NIL
  416.         s:=line+start
  417.         IF ((Val(s)>255) OR (Val(s)<0)) AND (i<>0)
  418.             PrintF('\tSKIPPED: "\s" - Value \d out of range (\d)!\n', errline, i+1, Val(s))
  419.             RETURN
  420.         ELSEIF ((Val(s)>79) OR (Val(s)<0)) AND (i=0)
  421.             PrintF('\tSKIPPED: "\s" - Invalid object index "\d"!\n', errline, Val(s))
  422.             RETURN
  423.         ELSE
  424.             rcd[i]:=Val(s)
  425.         ENDIF
  426.         IF(i=1) THEN StrCopy(wepname, s)
  427.         INC i
  428.         start:=end+1
  429.     UNTIL end=-1
  430.  
  431.     IF i<>14 THEN RETURN -> Check that the line contained exactly 14 values.
  432.  
  433.     NEW wep
  434.         IF    (wep.impvalues(rcd, wepname)<>1)
  435.             writeobvalues(rcd[0]*54, wep)
  436.             IF (verbose<>0) THEN PrintF('Imported weapon "\s" at index #\d.\n', wepname, rcd[0])
  437.         ELSE
  438.             PrintF('\tSkipped object #\d!\n', rcd[0])
  439.         ENDIF
  440.     END wep
  441.  
  442. ENDPROC
  443.  
  444. PROC printexamples() -> Print some examples of usage.
  445.     PrintF('\nExamples:\n\n')
  446.     PrintF('\tOBEdit obdata.dat\n\n')
  447.     PrintF('Print a list of objects found in file "obdata.dat".\n\n')
  448.     PrintF('\tOBEdit obdata.dat 12\n\n')
  449.     PrintF('Print details about object #12 in "obdata.dat".\n\n')
  450.     PrintF('\tOBEdit obdata.dat all\n\n')
  451.     PrintF('Prints detail about ALL objects in "obdata.dat".\n\n')
  452.     PrintF('\tOBEdit obdata.dat exportcsv data.csv\n\n')
  453.     PrintF('Export data in "obdata.dat" to a comma-separated ASCII file "data.csv".\n\n')
  454.     PrintF('\tOBEdit obdata.dat exportrff data.db\n\n')
  455.     PrintF('Export data in "obdata.dat" to a tab-separated RFF file "data.db".\n\n')
  456.     PrintF('\tOBEdit obdata.dat import data.whatever\n\n')
  457.     PrintF('Import data from file "data.whatever" (either tab- or comma-separated) to "obdata.dat".\n')
  458.     CleanUp()
  459. ENDPROC
  460.  
  461. ver: CHAR 0,'$VER: OBEdit 1.1 (28.05.99) By Kay Ove Ovesen <ai97koo@stud.hib.no>',10,13,0
  462.